package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.bean.Category;
import com.itheima.bean.Setmeal;
import com.itheima.bean.SetmealDish;
import com.itheima.dao.SetmealDao;
import com.itheima.dto.SetmealDto;
import com.itheima.exception.CustomException;
import com.itheima.service.CategoryService;
import com.itheima.service.SetmealDishService;
import com.itheima.service.SetmealService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author Tang
 * @date 2023/1/7
 */
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealDao, Setmeal> implements SetmealService {

    @Autowired
    private SetmealDao setmealDao;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private CategoryService categoryService;

    /**
     * 新增套餐
     * @param setmealDto
     */
    @Override
    public void addSetmealWithDish(SetmealDto setmealDto) {
        //0.开启事务（涉及到多张表的新增或修改）
        //1.校验数据库中是否存在该套餐名称
        /*LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Setmeal::getName, setmealDto.getName());
        int count = this.count(queryWrapper);*/
        int count = setmealDao.count(setmealDto.getName());
        if (count > 0) {
            throw new CustomException("该套餐名称【"+setmealDto.getName()+"】已存在！");
        }

        //2.保存套餐数据到setmeal套餐表
        this.save(setmealDto);

        //3.保存套餐菜品数据到setmeal_dish套餐菜品关系表
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        //3.1 关联套餐id
        for (SetmealDish setmealDish : setmealDishes) {
            setmealDish.setSetmealId(setmealDto.getId());
        }
        setmealDishService.saveBatch(setmealDishes);
    }

    /**
     * 套餐分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @Override
    public Page<SetmealDto> findPage(Integer page, Integer pageSize, String name) {
        //1.new Page<SetmealDto>创建分页对象，records、total、size....
        Page<SetmealDto> setmealDtoPage = new Page<>();

        //2.封装 Page<SetmealDto>数据：
        //2.1 构造分页对象 Page<Setmeal>(page, pageSize)
        Page<Setmeal> setmealPage = new Page<>(page, pageSize);

        //2.2 构造查询对象，可以根据套餐名称进行分页查询
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(name != null, Setmeal::getName, name);

        //2.3 调用自身的page方法，传入分页对象以及查询对象，最终得到Page<Setmeal>对象数据，里面records（List<Setmeal>）、total、size....
        this.page(setmealPage, queryWrapper);

        //2.4 Page<Setmeal>所有属性拷贝到Page<SetmealDto>，排除records属性
        BeanUtils.copyProperties(setmealPage, setmealDtoPage, "records");

        //2.5 封装Page<SetmealDto>的records属性：List<SetmealDto>
        List<SetmealDto> setmealDtoList = new ArrayList<>();
        List<Setmeal> setmealList = setmealPage.getRecords();
        //a.循环遍历List<Setmeal>
        for (Setmeal setmeal : setmealList) {
            //b.构造SetmealDto对象数据，设置setmeal属性
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(setmeal, setmealDto);
            //c.获取categoryName属性（根据分类id查询分类表）封装到SetmealDto
            Category category = categoryService.getById(setmeal.getCategoryId());
            setmealDto.setCategoryName(category.getName());
            //d.将SetmealDto对象添加到List<SetmealDto>
            setmealDtoList.add(setmealDto);
        }
        //2.6 设置Page<SetmealDto>对象的records属性：List<SetmealDto>
        setmealDtoPage.setRecords(setmealDtoList);

        //3.返回Page<SetmealDto>
        return setmealDtoPage;
    }

    /**
     * 删除套餐并且删除关联的套餐菜品数据
     * @param ids
     */
    @Override
    public void deleteWithSetmealDish(Long[] ids) {
        //0.开启事务
        //1.删除前检查套餐的状态，如果是售卖中的不允许删除
        List<Setmeal> setmeals = this.listByIds(Arrays.asList(ids));//select * from setmeal where id in (xx,xxx,xx)
        for (Setmeal setmeal : setmeals) {
            if (setmeal.getStatus() == 1) { //1代表起售 0代表停售
                throw new CustomException("该套餐正在售卖中，不允许删除！");
            }
        }

        //2.先删除套餐表里的数据setmeal
        this.removeByIds(Arrays.asList(ids));

        //3.再删除套餐菜品表的数据（根据setmel_id）
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SetmealDish::getSetmealId, ids); //select * from setmeal_dish where setmeal_id in (xx,xxx,xx)
        setmealDishService.remove(queryWrapper);
    }

    @Override
    public SetmealDto getSetmealWithDishs(String id) {
        SetmealDto setmealDto = new SetmealDto();
        Setmeal setmeal = this.getById(id);
        BeanUtils.copyProperties(setmeal, setmealDto);
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId, id);
        List<SetmealDish> setmealDishList = setmealDishService.list(queryWrapper);
        setmealDto.setSetmealDishes(setmealDishList);
        return setmealDto;
    }

    /**
     * 编辑套餐
     *
     * @param setmealDto 分类dto
     */
    @Override
    @Transactional
    public void updateSetmeal(SetmealDto setmealDto) {
        //修改套餐表中的数据
        this.updateById(setmealDto);
        //删除与之相关联的菜品后 再添加
        LambdaQueryWrapper<SetmealDish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SetmealDish::getSetmealId,setmealDto.getId());
        setmealDishService.remove(lqw);

        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        for (SetmealDish setmealDish : setmealDishes) {
            setmealDish.setSetmealId(setmealDto.getId());
        }
        setmealDishService.saveBatch(setmealDishes);
    }

    /**
     * 修改套餐的状态
     *
     * @param status 套餐的状态
     * @param ids    套餐的ids
     */
    @Override
    public void status(int status, String ids) {
        String[] idss = ids.split(",");
        for (String id : idss) {
            Setmeal setmeal = this.getById(id);
            setmeal.setStatus(status);
            this.updateById(setmeal);
        }
    }
}
